<!--
 * @Description: 设备点位图
 * @LastEditors: xzh
 * @LastEditTime: 2024-07-28 23:16:07
-->
<template>
  <DileDrawer
    v-model="equipPointParam.visible"
    :loading="equipPointParam.loading"
    size="60rem"
    @sure="hanldeSure"
  >
    <el-card shadow="never">
      <template #header>
        <span>{{ $t(`page.equipManageArr.equipTypeArr.equipPoint`) }}</span>
      </template>
      <div class="point-container">
        <!-- 点位背景图 -->
        <PointImg :pointInfo="equipPointParam.pointInfo" />

        <div class="point-content">
          <div>
            <span class="dile-group-title">
              {{
              $t(`page.equipManageArr.equipTypeArr.pointImg`)
              }}
            </span>
            <el-upload
              ref="uploadRef"
              list-type="picture-card"
              v-model:file-list="fileList"
              :limit="1"
              :accept="equipPointParam.imgType"
              :on-change="handleFileChange"
              :on-preview="handlePreview"
              :on-remove="handleRemove"
            >
              <el-icon>
                <Plus />
              </el-icon>
            </el-upload>
          </div>
          <div>
            <span class="dile-group-title">
              {{
              $t(`page.equipManageArr.equipTypeArr.pointInfo`)
              }}
            </span>
            <!-- 点位信息列表 -->
            <DileTable ref="dileTableRef">
              <template #preColumn>
                <vxe-column field="x" :title="$t('page.equipManageArr.equipTypeArr.xPosition')" />
                <vxe-column field="y" :title="$t('page.equipManageArr.equipTypeArr.yPosition')" />
                <vxe-column
                  :title="$t('page.equipManageArr.equipTypeArr.alarmInfo')"
                  :edit-render="{}"
                >
                  <template #default="{ row }">
                    <span>
                      {{
                      equipPointParam.alarmInfoArr
                      .filter((x: object_Inf) => row.alarmIds?.includes(x.id))
                      .map((x: object_Inf) => x.alarmName)
                      .join(",")
                      }}
                    </span>
                  </template>
                  <template #edit="{ row }">
                    <el-select
                      v-model="row.alarmIds"
                      multiple
                      collapse-tags
                      collapse-tags-tooltip
                      popper-class="vxe-table--ignore-clear"
                    >
                      <el-option
                        v-for="alarmInfo in equipPointParam.alarmInfoArr"
                        :key="alarmInfo.id"
                        :label="alarmInfo.alarmName"
                        :value="alarmInfo.id"
                      />
                    </el-select>
                  </template>
                </vxe-column>
              </template>
            </DileTable>
          </div>
        </div>
      </div>
    </el-card>
  </DileDrawer>
</template>

<script setup lang="ts">
import { ref, reactive, toRefs, provide, computed } from "vue";
import { object_Inf } from "@/utils/typings/index.type";
import { propsParam_Inf } from "@/components/dile-table/index.type";
import { ElNotification, UploadUserFile } from "element-plus";
import { useI18n } from "vue-i18n";
import DileDrawer from "@/components/dile-drawer/index.vue";
import { Plus } from "@element-plus/icons-vue";
import DileTable from "@/components/dile-table/index.vue";
import PointImg from "./point-img/index.vue";
import "viewerjs/dist/viewer.css";
import Viewer from "viewerjs";
import Dile_APi from "@/api";
import Dile_Methods from "@/utils/methods";
let { t } = useI18n();

let uploadRef = ref<any>();
/**
 * @Author: xzh
 * @Descripttion: 表单默认数据
 * @Param:
 */
let defaultData = () => ({
  pointImg: "", //点位图
  pointArr: [] //点位信息
});
/**
 * @Author: xzh
 * @Descripttion: 设备点位参数
 * @Param:
 */
let equipPointParam = reactive<object_Inf>({
  visible: false,
  loading: false,
  equipTypeId: "",
  alarmInfoArr: [],
  imgType: ["image/png", "image/jpeg", "image/jpg"],
  pointInfo: defaultData()
});

let maxFileLength = ref(0);

/**
 * @Author: xzh
 * @Description: 文件列表
 * @Param:
 * @param {*} computed
 */
let fileList = computed(() => {
  let { pointImg } = equipPointParam.pointInfo;
  return (!!pointImg
    ? [
        {
          url: Dile_Methods.getFileUrl(pointImg)
        }
      ]
    : []) as Array<UploadUserFile>;
});

/**
 * @Author: xzh
 * @Descripttion: 初始化
 * @Param:
 */
let init = async (typeId: string) => {
  let { loading } = toRefs(equipPointParam);
  try {
    loading.value = true;
    //加载点位信息
    let { pointInfo, alarmInfoArr } = await initPontInfo(typeId);
    Object.assign(equipPointParam, {
      visible: true,
      equipTypeId: typeId,
      alarmInfoArr,
      pointInfo
    });
    //加载表格数据
    propsParam.tableData = pointInfo.pointArr;
  } finally {
    loading.value = false;
  }
};
/**
 * @Author: xzh
 * @Description:加载点位信息
 * @Param:
 */
let initPontInfo = async (typeId: string) => {
  let alarmInfoArr = await Dile_APi.getEquipTypeAlarmInfoList(typeId);
  //根据设备类型获取点位信息
  let { fileId, pointArr: pointDataArr } = await Dile_APi.getEquipPointInfo(
    typeId
  );
  //反序列化点位信息
  let positionArr = (pointDataArr || []).map((x: object_Inf) => ({
    ...x,
    position: JSON.parse(x.position || {})
  }));

  let pointArr =
    //根据点位信息分组
    [...new Set(positionArr.map((x: object_Inf) => x.position.id))].map(
      pointId => {
        //获取点位信息
        let pointArr = positionArr.filter(
          (x: object_Inf) => x.position.id == pointId
        );
        //获取点位关联对个异常信息
        let alarmIds = pointArr.map((x: object_Inf) => x.id);
        return {
          ...(pointArr.at().position || {}),
          alarmIds,
          //获取异常对应安全等级
          level: [
            ...new Set(
              alarmInfoArr
                .filter(x => alarmIds.includes(x.id))
                .map(x => x.alarmLevel)
            )
          ]
        };
      }
    );

  return {
    pointInfo: {
      pointImg: fileId,
      pointArr
    },
    alarmInfoArr
  };
};
/**
 * @Author: xzh
 * @Descripttion: 文件状态改变时的钩子
 * @Param:
 */
let handleFileChange = (
  uploadFile: object_Inf,
  uploadFiles: Array<object_Inf>
) => {
  let currentLength = uploadFiles.length,
    { imgType } = equipPointParam;
  //文件上传防抖
  maxFileLength.value = Math.max(currentLength, maxFileLength.value);
  setTimeout(() => {
    if (currentLength == maxFileLength.value) {
      let files = uploadFiles.filter(x => !!imgType?.includes(x.raw.type));
      if (files.length == 0) {
        //提示成功
        ElNotification({
          message: t("common.message.pleaseUploadImgFile"),
          type: "warning"
        });
        uploadRef.value?.clearFiles();
        return false;
      }
      handleFileUpload(files);
    }
  });
};
/**
 * @Author: xzh
 * @Descripttion: 文件上传
 * @Param:
 * @param {*} uploadFiles
 */
let handleFileUpload = async (uploadFiles: Array<object_Inf>) => {
  let formData = new FormData(),
    { pointImg } = toRefs(equipPointParam.pointInfo);
  uploadFiles.forEach(item => {
    formData.append("file", item.raw);
  });
  //上传文件
  pointImg.value = await Dile_APi.uploadFiles(formData);
};
/**
 * @Author: xzh
 * @Description: 图片预览
 * @Param:
 * @param {*} uploadFile
 */
let handlePreview = (uploadFile: object_Inf) => {
  let { fileOid, url } = uploadFile;
  let viewer = new Viewer(
    document.querySelector(
      `.el-upload-list__item-thumbnail[src*='${fileOid || url}']`
    )!,
    {
      hidden: () => {
        viewer.destroy();
      }
    }
  );
  viewer.show();
};
/**
 * @Author: xzh
 * @Description: 图片删除
 * @Param:
 */
let handleRemove = () => {
  equipPointParam.pointInfo = defaultData();
  propsParam.tableData = equipPointParam.pointInfo.pointArr;
};

let hanldeSure = async () => {
  let { equipTypeId, loading, visible, pointInfo } = toRefs(equipPointParam),
    { pointImg, pointArr } = pointInfo.value || {};
  try {
    loading.value = true;
    //拼装保存格式
    let data = {
      typeId: equipTypeId.value,
      fileId: pointImg,
      pointArr: pointArr
        .map((point: object_Inf) => {
          let { id, x, y, alarmIds } = point;
          return alarmIds?.map((alarmId: string) => ({
            id: alarmId,
            position: JSON.stringify({ id, x, y })
          }));
        })
        .flat()
    };
    await Dile_APi.saveEquipPointInfo(data);
    //提示成功
    ElNotification({
      message: t("common.message.OperationSuccess"),
      type: "success"
    });
    //关闭弹框
    visible.value = false;
  } finally {
    loading.value = false;
  }
};

/**
 * @Author: xzh
 * @Descripttion: 表格参数
 * @Param:
 */
let propsParam = reactive<propsParam_Inf>({
  loading: false,
  tableData: equipPointParam.pointInfo.pointArr,
  editConfig: {
    trigger: "click",
    mode: "cell",
    autoClear: true
  },
  isPagination: false
});
provide("propsParam", propsParam);

defineExpose({
  init
});
</script>
<style lang="scss" scoped>
.el-card {
  overflow: auto;
}
.point-container {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--point-gap);
  // overflow: auto;

  .point-content {
    display: flex;
    flex: 12rem 0 0;
    height: 0;
    > div {
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: var(--point-gap);
      &:first-child {
        flex: 30% 0 0 !important;
      }
    }
  }
  --point-gap: 1rem;
}
</style>
